package com.tanhua.dubbo.server.api;

import cn.hutool.core.collection.CollUtil;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.tanhua.dubbo.server.pojo.Messages;
import com.tanhua.dubbo.server.vo.PageInfo;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.*;

/**
 * @Author 王加鑫
 * @Date 2021/09/16 22:00
 * @Since JDK 1.8
 */
@Service(version = "1.0.0")
public class MessagesApiImpl implements MessagesApi {


    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    /**
     * 新增后台消息操作
     * @param userId 发布动态的用户id
     * @param mid    动态id
     * @return
     */
    @Override
    public Boolean saveMessages(Long userId, ObjectId mid,Integer loveCount,Integer likeCount,Integer commentCount,Long createDate) {
        Messages messages = new Messages();
        messages.setId(ObjectId.get());
        messages.setMId(mid); //动态id
        messages.setCreateDate(createDate);
        messages.setLikeCount(likeCount); //点赞数
        messages.setLoveCount(loveCount); //喜欢数
        messages.setCommentCount(commentCount); //评论数
        messages.setUserId(userId); //发布动态的id
        messages.setState("3"); //默认为待审核状态
        messages.setTopState(1); //置顶状态
        messages.setForwardingCount(RandomUtil.randomInt(1000)); //转发数
        messages.setReportCount(0); //举报数
        this.mongoTemplate.save(messages);
        return true;
    }

    /**
     * 根据消息id查询消息表
     * @param id
     * @return
     */
    @Override
    public Messages queryMessages(String id) {
        Messages messages = new Messages();
        Criteria criteria = Criteria.where("id").is(new ObjectId(id));
        Query query = Query.query(criteria);
        messages = this.mongoTemplate.findOne(query, Messages.class);
        if(ObjectUtil.isNotEmpty(messages)){
            return messages;
        }
        return null;
    }


    @Override
    public PageInfo<Messages> queryMessagesList(Integer pageSize, Integer page, String sortProp, String sortOrder, String mid, String startTime, String endTime, Long userId) {
        PageInfo<Messages> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        PageRequest pageRequest = null;

        /**
         * 根据创建时间升序或者是降序排序
         */
        Sort sort = null;
        if(sortOrder.equals("ascending")){
            sort = Sort.by(Sort.Order.asc(sortProp));
        }else if(sortOrder.equals("descending")){
            sort = Sort.by(Sort.Order.desc(sortProp));
        }
        Criteria criteria = new Criteria();
        /**
         * userId ， state为必要条件
         */
        if(userId != null){
            criteria .and("userId").is(userId);
        }

        if(ObjectUtil.isNotEmpty(mid)){
            criteria.and("mId").is(new ObjectId(mid));
        }

        /**
         * 时间条件
         */
        //如果时间参数为空
        if(startTime == null || endTime == null){
            Query query = Query.query(criteria).with(sort).with(PageRequest.of(page-1,pageSize));
            List<Messages> messagesList = this.mongoTemplate.find(query, Messages.class);
            if(CollUtil.isEmpty(messagesList)){
                return pageInfo;
            }
            pageInfo.setRecords(messagesList);
            pageInfo.setTotal(Convert.toInt(this.mongoTemplate.count(query,Messages.class)));
            return pageInfo;
        }
        Date start = new Date(startTime);
        Date end = new Date(endTime);
        criteria.andOperator(Criteria.where("createDate").gte(start),Criteria.where("createDate").lte(end));
        Query query = Query.query(criteria).with(sort).with(pageRequest);
        List<Messages> messagesList = this.mongoTemplate.find(query, Messages.class);
        if(CollUtil.isEmpty(messagesList)){
            return pageInfo;
        }
        pageInfo.setRecords(messagesList);
        pageInfo.setTotal(Convert.toInt(this.mongoTemplate.count(query,Messages.class)));
        return pageInfo;

    }

    /**
     * 根据条件查询MessagesList数据
     * @param pageSize
     * @param page
     * @param sortProp
     * @param sortOrder
     * @param mid
     * @param startTime
     * @param endTime
     * @param userId
     * @param state
     * @return
     */
    @Override
    public PageInfo<Messages> queryMessagesList(Integer pageSize, Integer page, String sortProp, String sortOrder, String mid, String startTime, String endTime, Long userId, String state) {
        PageInfo<Messages> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        PageRequest pageRequest = null;
        /**
         * 根据创建时间升序或者是降序排序
         */
        if(sortOrder.equals("ascending")){
            pageRequest = PageRequest.of(page-1,pageSize,Sort.by(Sort.Order.asc(sortProp)));
        }else if(sortOrder.equals("descending")){
            pageRequest = PageRequest.of(page-1,pageSize,Sort.by(Sort.Order.desc(sortProp)));
        }

        Criteria criteria = null;
        //查所有
        if(state.equals("all")){
            criteria = new Criteria();
        }else{
            //根据state状态去查
            criteria = Criteria.where("state").is(state);
        }

        /**
         * userId ， state为必要条件
         */
        if(userId != null){
            criteria .and("userId").is(userId);

        }

        if(ObjectUtil.isNotEmpty(mid)){
            criteria.and("mId").is(new ObjectId(mid));
        }

        /**
         * 时间条件
         */
        if(startTime.equals("-1") || endTime.equals("-1") || startTime == null || endTime == null){
            Query query = Query.query(criteria).with(pageRequest);
            List<Messages> messagesList = this.mongoTemplate.find(query, Messages.class);
            if(CollUtil.isEmpty(messagesList)){
                return pageInfo;
            }
            pageInfo.setRecords(messagesList);
        }else if(ObjectUtil.isAllNotEmpty(startTime,endTime)){
            Date start = new Date(startTime);
            Date end = new Date(endTime);
            criteria.andOperator(Criteria.where("createDate").gte(start),Criteria.where("createDate").lte(end));
            Query query = Query.query(criteria).with(pageRequest);
            List<Messages> messagesList = this.mongoTemplate.find(query, Messages.class);
            if(CollUtil.isEmpty(messagesList)){
                return pageInfo;
            }
            pageInfo.setRecords(messagesList);
        }

        Integer count = this.queryMessagesCount(state);
        pageInfo.setTotal(count);
        return pageInfo;
    }

//    /**
//     * 查询不同审核状态的数量
//     * @param
//     * @return
//     */
//    @Override
//    public Map<String,Integer> queryStateCount() {
//        Criteria criteria = null;
//        Query query = null;
//        Map<String,Integer> map = new HashMap<>();
//        String[] states = {"all","3","4","5"};
//        for (String s : states) {
//            if(s.equals("all")){
//                criteria = new Criteria();
//                query = Query.query(criteria);
//                long count = this.mongoTemplate.count(query, Messages.class);
//                map.put(s,Convert.toInt(count));
//            }
//            if(s.equals("3")){
//                criteria = Criteria.where("state").is(s);
//                query = Query.query(criteria);
//                long count = this.mongoTemplate.count(query, Messages.class);
//                map.put(s,Convert.toInt(count));
//            }
//            if(s.equals("4")){
//                criteria = Criteria.where("state").is(s);
//                query = Query.query(criteria);
//                long count = this.mongoTemplate.count(query, Messages.class);
//                map.put(s,Convert.toInt(count));
//            }
//            if(s.equals("5")){
//                criteria = Criteria.where("state").is(s);
//                query = Query.query(criteria);
//                long count = this.mongoTemplate.count(query, Messages.class);
//                map.put(s,Convert.toInt(count));
//            }
//        }
//        return map;
//    }

    /**
     * 消息通过接口
     * 根据消息id修改数据
     * @param ids
     * @return
     */
    @Override
    public String messagesPast(String[] ids) {
        List<ObjectId> idList = new ArrayList<>();
        for (int i = 0; i < ids.length; i++) {
            idList.add(new ObjectId(ids[i]));
        }

        if(ArrayUtil.isNotEmpty(ids)){
            Query query = Query.query(Criteria.where("id").in(idList));
            Update update = Update.update("state","5");
            this.mongoTemplate.updateMulti(query,update,Messages.class);
            return "5";
        }
        return null;
    }

    /**
     * 消息拒绝接口
     * 根据消息id修改数据
     * @param ids
     * @return
     */
    @Override
    public String messagesReject(String[] ids) {
        List<ObjectId> idList = new ArrayList<>();
        for (int i = 0; i < ids.length; i++) {
            idList.add(new ObjectId(ids[i]));
        }

        if(ArrayUtil.isNotEmpty(ids)){
            Query query = Query.query(Criteria.where("id").in(idList));
            Update update = Update.update("state","4");
            this.mongoTemplate.updateMulti(query,update,Messages.class);
            return "4";
        }
        return null;
    }

    /**
     * 消息撤销
     * @param ids
     * @return
     */
    @Override
    public String messagesRevocation(String[] ids) {
        List<ObjectId> idList = new ArrayList<>();
        for (int i = 0; i < ids.length; i++) {
            idList.add(new ObjectId(ids[i]));
        }

        if(ArrayUtil.isNotEmpty(ids)){
            Query query = Query.query(Criteria.where("id").in(idList));
            Update update = Update.update("state","3");
            this.mongoTemplate.updateMulti(query,update,Messages.class);
            return "3";
        }
        return null;
    }

    /**
     * 消息置顶
     * 一个用户只能一条动态可以置顶
     * @param id
     * @return
     */
    @Override
    public String messagesTop(String id) {

        if(ObjectUtil.isEmpty(id)){
            return null;
        }
        //根据id去messages表中查询当前用户
        Query query = Query.query(Criteria.where("id").is(new ObjectId(id)));
        Messages messages = this.mongoTemplate.findOne(query, Messages.class);
        //发布这条动态的用户
        Long userId = messages.getUserId();
        String redisKey = "MESSAGES_USERID_" + userId;
        String hashKey = "HASH_KEY";
        Boolean flag = this.isTop(userId);
        //如果已经有动态已经是置顶状态了，判断是不是当前这条动态(一个userId可以对应多条动态)
        if(flag){
            //需要去mongodb数据库中查询是否有topState字段为2的数据
            query = Query.query(Criteria.where("userId").is(userId));
            List<Messages> messagesList = this.mongoTemplate.find(query, Messages.class);
            for (Messages m : messagesList) {
                //有动态置顶
                if(m.getTopState() == 2){
                    //是自己置顶就返回null
                    if(m.getId().toHexString().equals(id)){
                        return null;
                    }else { //是别的动态置顶就取消它的置顶
                        //修改其状态为非置顶
                        this.updateStateToUnTop(m.getId());
                        //将自己设置为置顶状态
                        this.updateStateToTop(new ObjectId(id));
                        return "1";
                    }
                }
            }
        }

        //没有动态置顶，直接将自己设置为置顶状态,修改数据库中的topState字段
        this.updateStateToTop(new ObjectId(id));
        //给redis缓存中添加一条数据
        this.redisTemplate.opsForHash().put(redisKey,hashKey,"1");
        return "1";
    }

    private Boolean isTop(Long userId){
        String redisKey = "MESSAGES_USERID_" + userId;
        String hashKey = "HASH_KEY";
        //判断是否包含这个key
        Boolean result = this.redisTemplate.opsForHash().hasKey(redisKey,hashKey);
        return  result;
    }

    /**
     * 修改消息状态为非置顶
     */
    private void updateStateToUnTop(ObjectId id) {
        Query query = Query.query(Criteria.where("id").is(id));
        Update update = Update.update("topState",1);
        this.mongoTemplate.updateFirst(query,update,Messages.class);
    }

    /**
     * 修改消息状态为置顶
     */
    private void updateStateToTop(ObjectId id) {
        Query query = Query.query(Criteria.where("id").is(id));
        Update update = Update.update("topState",2);
        this.mongoTemplate.updateFirst(query,update,Messages.class);
    }

    @Override
    public Integer queryMessagesCount(String state) {
        if(ObjectUtil.isEmpty(state)){
            return null;
        }
        Query query = null;
        if(state.equals("all")){
            query = new Query();
        }else {
            query = Query.query(Criteria.where("state").is(state));
        }
        long count = this.mongoTemplate.count(query, Messages.class);
        return Convert.toInt(count);
    }

    /**
     * 取消置顶
     * @param id
     * @return
     */
    @Override
    public String messagesUnTop(String id) {
        if(ObjectUtil.isEmpty(id)){
            return null;
        }
        Query query = Query.query(Criteria.where("id").is(new ObjectId(id)));
        Messages messages = this.mongoTemplate.findOne(query,Messages.class);
        //发布这条动态的用户
        Long userId = messages.getUserId();
        String redisKey = "MESSAGES_USERID_" + userId;
        String hashKey = "HASH_KEY";
        Boolean flag = this.isTop(userId);
        if(!flag){
            //如果当前用户没有一条动态处于置顶状态，返回null
            return null;
        }
        //走到这说明当前用户有一条动态是处于置顶状态
        query = Query.query(Criteria.where("userId").is(userId));
        List<Messages> messagesList = this.mongoTemplate.find(query, Messages.class);
        for (Messages m : messagesList) {
            //找到哪条动态置顶
            if(m.getTopState() == 2){
                //修改该条动态在数据库中的字段
                this.updateStateToUnTop(new ObjectId(id));
                //修改redis中的状态值
                this.redisTemplate.opsForHash().delete(redisKey,hashKey);
            }
        }
        return "1";
    }

}
